<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>webdoc</title>
    <link rel="stylesheet" type="text/css" href="../static/css/main.css">
</head>
<body>
<div class="nav">
    <div class="logo">
        
            webdoc
        
    </div>
<ul><li><a href="../index.html">0.Async</a></li><li><a href="../html/0.editor.html">0.editor</a></li><li><a href="../html/0.module.html">0.module</a></li><li><a href="../html/1.ES2015.html">1.ES2015</a></li><li><a href="../html/2.Promise.html">2.Promise</a></li><li><a href="../html/3.Node.html">3.Node</a></li><li><a href="../html/4.NodeInstall.html">4.NodeInstall</a></li><li><a href="../html/5.REPL.html">5.REPL</a></li><li><a href="../html/6.NodeCore.html">6.NodeCore</a></li><li><a href="../html/7.module&NPM.html">7.module&NPM</a></li><li><a href="../html/8.Encoding.html">8.Encoding</a></li><li><a href="../html/9.Buffer.html">9.Buffer</a></li><li><a href="../html/10.fs.html">10.fs</a></li><li><a href="../html/11.Stream-1.html">11.Stream-1</a></li><li><a href="../html/11.Stream-2.html">11.Stream-2</a></li><li><a href="../html/11.Stream-3.html">11.Stream-3</a></li><li><a href="../html/11.Stream-4.html">11.Stream-4</a></li><li><a href="../html/12-Network-2.html">12-Network-2</a></li><li><a href="../html/12.NetWork-3.html">12.NetWork-3</a></li><li><a href="../html/12.Network-1.html">12.Network-1</a></li><li><a href="../html/13.tcp.html">13.tcp</a></li><li><a href="../html/14.http-1.html">14.http-1</a></li><li><a href="../html/14.http-2.html">14.http-2</a></li><li><a href="../html/15.compress.html">15.compress</a></li><li><a href="../html/16.crypto.html">16.crypto</a></li><li><a href="../html/17.process.html">17.process</a></li><li><a href="../html/18.yargs.html">18.yargs</a></li><li><a href="../html/19.cache.html">19.cache</a></li><li><a href="../html/20.action.html">20.action</a></li><li><a href="../html/21.https.html">21.https</a></li><li><a href="../html/22.cookie.html">22.cookie</a></li><li><a href="../html/23.session.html">23.session</a></li><li><a href="../html/24.express-1.html">24.express-1</a></li><li><a href="../html/24.express-2.html">24.express-2</a></li><li><a href="../html/24.express-3.html">24.express-3</a></li><li><a href="../html/24.express-4.html">24.express-4</a></li><li><a href="../html/25.koa-1.html">25.koa-1</a></li><li><a href="../html/26.webpack-1-basic.html">26.webpack-1-basic</a></li><li><a href="../html/26.webpack-2-optimize.html">26.webpack-2-optimize</a></li><li><a href="../html/26.webpack-3.tapable.html">26.webpack-3.tapable</a></li><li><a href="../html/26.webpack-4-AST.html">26.webpack-4-AST</a></li><li><a href="../html/26.webpack-5-source.html">26.webpack-5-source</a></li><li><a href="../html/26.webpack-6-loader.html">26.webpack-6-loader</a></li><li><a href="../html/26.webpack-7-plugin.html">26.webpack-7-plugin</a></li><li><a href="../html/26.webpack-8-hand.html">26.webpack-8-hand</a></li><li><a href="../html/27.react-1.html">27.react-1</a></li><li><a href="../html/27.react-2.html">27.react-2</a></li><li><a href="../html/27.react-3.html">27.react-3</a></li><li><a href="../html/27.react-4-immutable.html">27.react-4-immutable</a></li><li><a href="../html/27.react-5-react-dom-diff.html">27.react-5-react-dom-diff</a></li><li><a href="../html/27.react-6.html">27.react-6</a></li><li><a href="../html/28.react-mobx.html">28.react-mobx</a></li><li><a href="../html/28.redux-0.html">28.redux-0</a></li><li><a href="../html/28.redux-1.html">28.redux-1</a></li><li><a href="../html/28.redux-2-中间件.html">28.redux-2-中间件</a></li><li class="active"><a href="../html/28.redux-3-saga.html">28.redux-3-saga</a></li><li><a href="../html/28.redux-jwt-back.html">28.redux-jwt-back</a></li><li><a href="../html/28.redux-jwt-front.html">28.redux-jwt-front</a></li><li><a href="../html/29.mongodb-1.html">29.mongodb-1</a></li><li><a href="../html/29.mongodb-2.html">29.mongodb-2</a></li><li><a href="../html/29.mongodb-3.html">29.mongodb-3</a></li><li><a href="../html/29.mongodb-4.html">29.mongodb-4</a></li><li><a href="../html/29.mongodb-5.html">29.mongodb-5</a></li><li><a href="../html/29.mongodb-6.html">29.mongodb-6</a></li><li><a href="../html/30.cms-1-mysql.html">30.cms-1-mysql</a></li><li><a href="../html/30.cms-2-mysql.html">30.cms-2-mysql</a></li><li><a href="../html/30.cms-3-mysql.html">30.cms-3-mysql</a></li><li><a href="../html/30.cms-4-egg.html">30.cms-4-egg</a></li><li><a href="../html/30.cms-5-api.html">30.cms-5-api</a></li><li><a href="../html/30.cms-6-roadhog.html">30.cms-6-roadhog</a></li><li><a href="../html/30.cms-7-umi.html">30.cms-7-umi</a></li><li><a href="../html/30.cms-8-dva.html">30.cms-8-dva</a></li><li><a href="../html/30.cms-9-dva.html">30.cms-9-dva</a></li><li><a href="../html/30.cms-10-dva.html">30.cms-10-dva</a></li><li><a href="../html/30.cms-11-front.html">30.cms-11-front</a></li><li><a href="../html/31.cms-12-api.html">31.cms-12-api</a></li><li><a href="../html/31.cms-13-front.html">31.cms-13-front</a></li><li><a href="../html/31.cms-14-deploy.html">31.cms-14-deploy</a></li><li><a href="../html/32.ant.html">32.ant</a></li><li><a href="../html/33.redis.html">33.redis</a></li><li><a href="../html/34.unittest.html">34.unittest</a></li><li><a href="../html/35.jwt.html">35.jwt</a></li><li><a href="../html/36.websocket-1.html">36.websocket-1</a></li><li><a href="../html/36.websocket-2.html">36.websocket-2</a></li><li><a href="../html/38.chat-api-1.html">38.chat-api-1</a></li><li><a href="../html/38.chat-api-2.html">38.chat-api-2</a></li><li><a href="../html/38.chat-3.html">38.chat-3</a></li><li><a href="../html/38.chat-api-3.html">38.chat-api-3</a></li><li><a href="../html/38.chat.html">38.chat</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/39.crawl-0.html">39.crawl-0</a></li><li><a href="../html/39.crawl-1.html">39.crawl-1</a></li><li><a href="../html/39.crawl-2.html">39.crawl-2</a></li><li><a href="../html/40.deploy.html">40.deploy</a></li><li><a href="../html/41.safe.html">41.safe</a></li><li><a href="../html/42.test.html">42.test</a></li><li><a href="../html/43.nginx.html">43.nginx</a></li><li><a href="../html/44.enzyme.html">44.enzyme</a></li><li><a href="../html/45.docker.html">45.docker</a></li><li><a href="../html/46.elastic.html">46.elastic</a></li><li><a href="../html/47.oauth.html">47.oauth</a></li><li><a href="../html/48.wxpay.html">48.wxpay</a></li><li><a href="../html/49.nunjucks.html">49.nunjucks</a></li><li><a href="../html/50.ketang.html">50.ketang</a></li><li><a href="../html/index.html">index</a></li><li><a href="../html/51.typescript.html">51.typescript</a></li><li><a href="../html/52.UML.html">52.UML</a></li><li><a href="../html/53.design.html">53.design</a></li><li><a href="../html/index.html">index</a></li></ul></div>


<div class="warpper">

    <div class="page-toc">
        <ul><li><a href="#t01. redux-saga">1. redux-saga</a></li><li><a href="#t12. redux-saga工作原理">2. redux-saga工作原理</a></li><li><a href="#t23. redux-saga分类">3. redux-saga分类</a></li><li><a href="#t35. 跑通saga">5. 跑通saga</a><ul><li><a href="#t45.1 index.js">5.1 index.js</a></li><li><a href="#t55.2 sagas.js">5.2 sagas.js</a></li><li><a href="#t65.3 Counter.js">5.3 Counter.js</a></li><li><a href="#t75.4 index.js">5.4 index.js</a></li><li><a href="#t85.5 actions.js">5.5 actions.js</a></li><li><a href="#t95.6 action-types.js">5.6 action-types.js</a></li><li><a href="#t105.7 reducer.js">5.7 reducer.js</a></li></ul></li><li><a href="#t116. 实现计数器">6. 实现计数器</a><ul><li><a href="#t126.1 src/saga.js">6.1 src/saga.js</a></li><li><a href="#t136.2 action-types.js">6.2 action-types.js</a></li><li><a href="#t146.3 actions.js">6.3 actions.js</a></li></ul></li><li><a href="#t157.日志记录器">7.日志记录器</a></li><li><a href="#t168.日志记录器">8.日志记录器</a><ul><li><a href="#t178.1 saga.js">8.1 saga.js</a></li></ul></li><li><a href="#t189. 支持takeEvery">9. 支持takeEvery</a><ul><li><a href="#t199.1 saga.js">9.1 saga.js</a></li><li><a href="#t209.2 redux-saga/index.js">9.2 redux-saga/index.js</a></li><li><a href="#t219.3 redux-saga/index.js">9.3 redux-saga/index.js</a></li></ul></li><li><a href="#t2210 支持promise">10 支持promise</a><ul><li><a href="#t2310.1 saga.js">10.1 saga.js</a></li><li><a href="#t2410.2 redux-saga/index.js">10.2 redux-saga/index.js</a></li></ul></li><li><a href="#t2511 支持 call">11 支持 call</a><ul><li><a href="#t2611.1 sagas.js">11.1 sagas.js</a></li><li><a href="#t2711.2 effects.js">11.2 effects.js</a></li><li><a href="#t2811.3 saga.js">11.3 saga.js</a></li></ul></li><li><a href="#t2912. 支持all">12. 支持all</a><ul><li><a href="#t3012.1 使用">12.1 使用</a></li><li><a href="#t3112.2 effects">12.2 effects</a></li><li><a href="#t3212.3 redux-saga/index.js">12.3 redux-saga/index.js</a></li></ul></li><li><a href="#t3313. 资源">13. 资源</a><ul><li><a href="#t3413.1 Iterator">13.1 Iterator</a></li></ul></li></ul>
    </div>
    
    <div class="content markdown-body">
        <h2 id="t01. redux-saga">1. redux-saga <a href="#t01. redux-saga"> # </a></h2>
<ul>
<li><a href="https://redux-saga-in-chinese.js.org/">redux-saga</a> &#x662F;&#x4E00;&#x4E2A; redux &#x7684;&#x4E2D;&#x95F4;&#x4EF6;&#xFF0C;&#x800C;&#x4E2D;&#x95F4;&#x4EF6;&#x7684;&#x4F5C;&#x7528;&#x662F;&#x4E3A; redux &#x63D0;&#x4F9B;&#x989D;&#x5916;&#x7684;&#x529F;&#x80FD;&#x3002;</li>
<li>&#x5728; reducers &#x4E2D;&#x7684;&#x6240;&#x6709;&#x64CD;&#x4F5C;&#x90FD;&#x662F;&#x540C;&#x6B65;&#x7684;&#x5E76;&#x4E14;&#x662F;&#x7EAF;&#x7CB9;&#x7684;&#xFF0C;&#x5373; reducer &#x90FD;&#x662F;&#x7EAF;&#x51FD;&#x6570;&#xFF0C;&#x7EAF;&#x51FD;&#x6570;&#x662F;&#x6307;&#x4E00;&#x4E2A;&#x51FD;&#x6570;&#x7684;&#x8FD4;&#x56DE;&#x7ED3;&#x679C;&#x53EA;&#x4F9D;&#x8D56;&#x4E8E;&#x5B83;&#x7684;&#x53C2;&#x6570;&#xFF0C;&#x5E76;&#x4E14;&#x5728;&#x6267;&#x884C;&#x8FC7;&#x7A0B;&#x4E2D;&#x4E0D;&#x4F1A;&#x5BF9;&#x5916;&#x90E8;&#x4EA7;&#x751F;&#x526F;&#x4F5C;&#x7528;&#xFF0C;&#x5373;&#x7ED9;&#x5B83;&#x4F20;&#x4EC0;&#x4E48;&#xFF0C;&#x5C31;&#x5410;&#x51FA;&#x4EC0;&#x4E48;&#x3002;</li>
<li>&#x4F46;&#x662F;&#x5728;&#x5B9E;&#x9645;&#x7684;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x5E0C;&#x671B;&#x505A;&#x4E00;&#x4E9B;&#x5F02;&#x6B65;&#x7684;&#xFF08;&#x5982;Ajax&#x8BF7;&#x6C42;&#xFF09;&#x4E14;&#x4E0D;&#x7EAF;&#x7CB9;&#x7684;&#x64CD;&#x4F5C;&#xFF08;&#x5982;&#x6539;&#x53D8;&#x5916;&#x90E8;&#x7684;&#x72B6;&#x6001;&#xFF09;&#xFF0C;&#x8FD9;&#x4E9B;&#x5728;&#x51FD;&#x6570;&#x5F0F;&#x7F16;&#x7A0B;&#x8303;&#x5F0F;&#x4E2D;&#x88AB;&#x79F0;&#x4E3A;&#x201C;&#x526F;&#x4F5C;&#x7528;&#x201D;&#x3002;</li>
</ul>
<blockquote>
<p>redux-saga &#x5C31;&#x662F;&#x7528;&#x6765;&#x5904;&#x7406;&#x4E0A;&#x8FF0;&#x526F;&#x4F5C;&#x7528;&#xFF08;&#x5F02;&#x6B65;&#x4EFB;&#x52A1;&#xFF09;&#x7684;&#x4E00;&#x4E2A;&#x4E2D;&#x95F4;&#x4EF6;&#x3002;&#x5B83;&#x662F;&#x4E00;&#x4E2A;&#x63A5;&#x6536;&#x4E8B;&#x4EF6;&#xFF0C;&#x5E76;&#x53EF;&#x80FD;&#x89E6;&#x53D1;&#x65B0;&#x4E8B;&#x4EF6;&#x7684;&#x8FC7;&#x7A0B;&#x7BA1;&#x7406;&#x8005;&#xFF0C;&#x4E3A;&#x4F60;&#x7684;&#x5E94;&#x7528;&#x7BA1;&#x7406;&#x590D;&#x6742;&#x7684;&#x6D41;&#x7A0B;&#x3002;</p>
</blockquote>
<h2 id="t12. redux-saga&#x5DE5;&#x4F5C;&#x539F;&#x7406;">2. redux-saga&#x5DE5;&#x4F5C;&#x539F;&#x7406; <a href="#t12. redux-saga&#x5DE5;&#x4F5C;&#x539F;&#x7406;"> # </a></h2>
<ul>
<li>sages &#x91C7;&#x7528; Generator &#x51FD;&#x6570;&#x6765; yield Effects&#xFF08;&#x5305;&#x542B;&#x6307;&#x4EE4;&#x7684;&#x6587;&#x672C;&#x5BF9;&#x8C61;&#xFF09;</li>
<li>Generator &#x51FD;&#x6570;&#x7684;&#x4F5C;&#x7528;&#x662F;&#x53EF;&#x4EE5;&#x6682;&#x505C;&#x6267;&#x884C;&#xFF0C;&#x518D;&#x6B21;&#x6267;&#x884C;&#x7684;&#x65F6;&#x5019;&#x4ECE;&#x4E0A;&#x6B21;&#x6682;&#x505C;&#x7684;&#x5730;&#x65B9;&#x7EE7;&#x7EED;&#x6267;&#x884C;</li>
<li>Effect &#x662F;&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x8BE5;&#x5BF9;&#x8C61;&#x5305;&#x542B;&#x4E86;&#x4E00;&#x4E9B;&#x7ED9; middleware &#x89E3;&#x91CA;&#x6267;&#x884C;&#x7684;&#x4FE1;&#x606F;&#x3002;</li>
<li>&#x4F60;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4F7F;&#x7528; effects API &#x5982; fork&#xFF0C;call&#xFF0C;take&#xFF0C;put&#xFF0C;cancel &#x7B49;&#x6765;&#x521B;&#x5EFA; Effect&#x3002; </li>
</ul>
<h2 id="t23. redux-saga&#x5206;&#x7C7B;">3. redux-saga&#x5206;&#x7C7B; <a href="#t23. redux-saga&#x5206;&#x7C7B;"> # </a></h2>
<ul>
<li>worker saga &#x505A;&#x5DE6;&#x53F3;&#x7684;&#x5DE5;&#x4F5C;&#xFF0C;&#x5982;&#x8C03;&#x7528;API&#xFF0C;&#x8FDB;&#x884C;&#x5F02;&#x6B65;&#x8BF7;&#x6C42;&#xFF0C;&#x83B7;&#x53D6;&#x5F02;&#x6B65;&#x5C01;&#x88C5;&#x7ED3;&#x679C;</li>
<li>watcher saga &#x76D1;&#x542C;&#x88AB;dispatch&#x7684;actions,&#x5F53;&#x63A5;&#x53D7;&#x5230;action&#x6216;&#x8005;&#x77E5;&#x9053;&#x5176;&#x88AB;&#x89E6;&#x53D1;&#x65F6;&#xFF0C;&#x8C03;&#x7528;worker&#x6267;&#x884C;&#x4EFB;&#x52A1;</li>
<li>root saga  &#x7ACB;&#x5373;&#x542F;&#x52A8;saga&#x7684;&#x552F;&#x4E00;&#x5165;&#x53E3;</li>
</ul>
<h2 id="t35. &#x8DD1;&#x901A;saga">5. &#x8DD1;&#x901A;saga <a href="#t35. &#x8DD1;&#x901A;saga"> # </a></h2>
<h3 id="t45.1 index.js">5.1 index.js <a href="#t45.1 index.js"> # </a></h3>
<p>src/index.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-dom&apos;</span>;
<span class="hljs-keyword">import</span> Counter <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./components/Counter&apos;</span>;
<span class="hljs-keyword">import</span> {Provider} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-redux&apos;</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./store&apos;</span>;
ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">Counter</span>/&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>,<span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">&apos;#root&apos;</span>));
</code></pre>
<h3 id="t55.2 sagas.js">5.2 sagas.js <a href="#t55.2 sagas.js"> # </a></h3>
<p>src/sagas.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">rootSaga</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;rootSaga&apos;</span>);
}
</code></pre>
<h3 id="t65.3 Counter.js">5.3 Counter.js <a href="#t65.3 Counter.js"> # </a></h3>
<p>src/components/Counter.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>
<span class="hljs-keyword">import</span> {connect} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-redux&apos;</span>;
<span class="hljs-keyword">import</span> actions <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../store/actions&apos;</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{this.props.number}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.props.increment}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
      )
  }
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> connect(
    <span class="hljs-function"><span class="hljs-params">state</span> =&gt;</span> state,
    actions
)(Counter);
</code></pre>
<h3 id="t75.4 index.js">5.4 index.js <a href="#t75.4 index.js"> # </a></h3>
<p>src/store/index.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {createStore, applyMiddleware} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux&apos;</span>;
<span class="hljs-keyword">import</span> reducer <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./reducer&apos;</span>;
<span class="hljs-keyword">import</span> createSagaMiddleware <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux-saga&apos;</span>;
<span class="hljs-keyword">import</span> {rootSaga} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../saga&apos;</span>;
<span class="hljs-keyword">let</span> sagaMiddleware=createSagaMiddleware();
<span class="hljs-keyword">let</span> store=applyMiddleware(sagaMiddleware)(createStore)(reducer);
sagaMiddleware.run(rootSaga);
<span class="hljs-built_in">window</span>.store=store;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> store;
</code></pre>
<h3 id="t85.5 actions.js">5.5 actions.js <a href="#t85.5 actions.js"> # </a></h3>
<p>src/store/actions.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> types <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./action-types&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    increment() {
        <span class="hljs-keyword">return</span> {<span class="hljs-attr">type</span>:types.INCREMENT}
    }
}
</code></pre>
<h3 id="t95.6 action-types.js">5.6 action-types.js <a href="#t95.6 action-types.js"> # </a></h3>
<p>src/store/action-types.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT=<span class="hljs-string">&apos;INCREMENT&apos;</span>;
</code></pre>
<h3 id="t105.7 reducer.js">5.7 reducer.js <a href="#t105.7 reducer.js"> # </a></h3>
<p>rc/store/reducer.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> types <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./action-types&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">state={number:<span class="hljs-number">0</span>},action</span>) </span>{
    <span class="hljs-keyword">switch</span>(action.type){
        <span class="hljs-keyword">case</span> types.INCREMENT:
            <span class="hljs-keyword">return</span> {<span class="hljs-attr">number</span>: state.number+<span class="hljs-number">1</span>};
        <span class="hljs-keyword">default</span>:
            <span class="hljs-keyword">return</span> state;
    }
}
</code></pre>
<h2 id="t116. &#x5B9E;&#x73B0;&#x8BA1;&#x6570;&#x5668;">6. &#x5B9E;&#x73B0;&#x8BA1;&#x6570;&#x5668; <a href="#t116. &#x5B9E;&#x73B0;&#x8BA1;&#x6570;&#x5668;"> # </a></h2>
<h3 id="t126.1 src/saga.js">6.1 src/saga.js <a href="#t126.1 src/saga.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {takeEvery,put} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux-saga/effects&apos;</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> types <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./store/action-types&apos;</span>;
<span class="hljs-keyword">const</span> delay=<span class="hljs-function"><span class="hljs-params">ms</span> =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve,reject</span>) =&gt;</span> {
    setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        resolve();
    },ms);
});
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">1000</span>);
    <span class="hljs-keyword">yield</span> put({<span class="hljs-attr">type</span>:types.INCREMENT});
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">rootSaga</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> takeEvery(types.INCREMENT_ASYNC,increment);
}
</code></pre>
<h3 id="t136.2 action-types.js">6.2 action-types.js <a href="#t136.2 action-types.js"> # </a></h3>
<p>src/store/action-types.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT_ASYNC=<span class="hljs-string">&apos;INCREMENT_ASYNC&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT=<span class="hljs-string">&apos;INCREMENT&apos;</span>;
</code></pre>
<h3 id="t146.3 actions.js">6.3 actions.js <a href="#t146.3 actions.js"> # </a></h3>
<p> src/store/actions.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> types <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./action-types&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    increment() {
        <span class="hljs-keyword">return</span> {<span class="hljs-attr">type</span>:types.INCREMENT_ASYNC}
    }
}
</code></pre>
<h2 id="t157.&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;">7.&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668; <a href="#t157.&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;"> # </a></h2>
<ul>
<li>&#x6700;&#x591A;&#x589E;&#x52A0;&#x5230;3&#xFF0C;&#x5230;&#x8FBE;&#x6700;&#x5927;&#x503C;&#x7684;&#x65F6;&#x5019;&#x5C31;&#x4E0D;&#x518D;&#x589E;&#x52A0;</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {put,take} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux-saga/effects&apos;</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> types <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./store/action-types&apos;</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> put({<span class="hljs-attr">type</span>:types.INCREMENT});
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">rootSaga</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i=<span class="hljs-number">0</span>;i&lt;<span class="hljs-number">3</span>;i++){
        <span class="hljs-keyword">let</span> action=<span class="hljs-keyword">yield</span> take(types.INCREMENT_ASYNC);
        <span class="hljs-keyword">yield</span> put({<span class="hljs-attr">type</span>:types.INCREMENT});
    }
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;&#x5DF2;&#x7ECF;&#x8FBE;&#x5230;&#x6700;&#x5927;&#x503C;&apos;</span>);
}
</code></pre>
<p>redux-saga/index.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createSagaMiddleware</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createChannel</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">let</span> listener={};
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subscribe</span>(<span class="hljs-params">actionType,cb</span>) </span>{
            listener[actionType]=cb;
        }
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">publish</span>(<span class="hljs-params">action</span>) </span>{
            <span class="hljs-keyword">debugger</span>;
            <span class="hljs-keyword">if</span> (listener[action.type]) {
                <span class="hljs-keyword">let</span> temp=listener[action.type];
                <span class="hljs-keyword">delete</span> listener[action.type];
                temp(action);
            }
        }
        <span class="hljs-keyword">return</span> {subscribe,publish}
    }
    <span class="hljs-keyword">let</span> channel=createChannel();
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sagaMiddleware</span>(<span class="hljs-params">{getState,dispatch}</span>) </span>{
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">run</span>(<span class="hljs-params">generator</span>) </span>{
            <span class="hljs-keyword">let</span> it=generator();
            <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">next</span>(<span class="hljs-params">action</span>) </span>{
                <span class="hljs-keyword">debugger</span>;
                <span class="hljs-keyword">let</span> {<span class="hljs-attr">value</span>:effect,done} = it.next(action);
                <span class="hljs-keyword">if</span> (!done) {
                    <span class="hljs-keyword">switch</span> (effect.type) {
                        <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;take&apos;</span>:
                            channel.subscribe(effect.actionType,next);
                            <span class="hljs-keyword">break</span>;
                        <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;put&apos;</span>:
                            dispatch(effect.action);
                            next();
                            <span class="hljs-keyword">break</span>;
                        <span class="hljs-keyword">default</span>:
                    }
                }
            }
            next();
        }
        sagaMiddleware.run=run;
        <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">next</span>) </span>{
            <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">action</span>) </span>{
                <span class="hljs-keyword">debugger</span>;
                channel.publish(action);
                next(action);
            }
        }
    }
    <span class="hljs-keyword">return</span> sagaMiddleware;
}
</code></pre>
<p>redux-saga/index.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">take</span>(<span class="hljs-params">actionType</span>) </span>{
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">type</span>:<span class="hljs-string">&apos;take&apos;</span>,
        actionType
    }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">put</span>(<span class="hljs-params">action</span>) </span>{
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">type</span>: <span class="hljs-string">&apos;put&apos;</span>,
        action
    }
}
</code></pre>
<h2 id="t168.&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;">8.&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668; <a href="#t168.&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;"> # </a></h2>
<ul>
<li>&#x5185;&#x5D4C;generator<h3 id="t178.1 saga.js">8.1 saga.js <a href="#t178.1 saga.js"> # </a></h3>
```js
import {put,take} from &apos;./redux-saga/effects&apos;;
import * as types from &apos;./store/action-types&apos;;
const delay=ms =&gt; new Promise((resolve,reject) =&gt; {
  setTimeout(() =&gt; {<pre><code>  resolve();
</code></pre>  },ms);
});
export function* increment() {
  //yield delay(1000);
  yield put({type:types.INCREMENT});
}</li>
</ul>
<p>export function* rootSaga() {
    for (let i=0;i&lt;3;i++){
        let action=yield take(types.INCREMENT_ASYNC);
        yield increment();
    }
    console.log(&apos;&#x5DF2;&#x7ECF;&#x8FBE;&#x5230;&#x6700;&#x5927;&#x503C;&apos;);
}</p>
<pre><code>### 8.2 redux-saga/index.js
```diff
    function sagaMiddleware({getState,dispatch}) {
        function run(generator) {
+            let it= typeof generator == &apos;function&apos;? generator():generator;
            function next(action) {
                let {value:effect,done} = it.next(action);
                if (!done) {
+                    if (typeof effect[Symbol.iterator]==&apos;function&apos;) {
+                        run(effect);
+                        next();
+                    } else {
                        switch (effect.type) {
                            case &apos;take&apos;:
                                channel.subscribe(effect.actionType,next);
                                break;
                            case &apos;put&apos;:
                                dispatch(effect.action);
                                next();
                                break;
                            default:
                        }
                    }
                }
            }
            next();
        }
        sagaMiddleware.run=run;
        return function (next) {
            return function (action) {
                channel.publish(action);
                next(action);
            }
        }
    }
</code></pre><h2 id="t189. &#x652F;&#x6301;takeEvery">9. &#x652F;&#x6301;takeEvery <a href="#t189. &#x652F;&#x6301;takeEvery"> # </a></h2>
<h3 id="t199.1 saga.js">9.1 saga.js <a href="#t199.1 saga.js"> # </a></h3>
<pre><code class="lang-diff">import {put,take,takeEvery} from &apos;./redux-saga/effects&apos;;
import * as types from &apos;./store/action-types&apos;;
const delay=ms =&gt; new Promise((resolve,reject) =&gt; {
    setTimeout(() =&gt; {
        resolve();
    },ms);
});
export function* increment() {
    yield put({type:types.INCREMENT});
}

export function* rootSaga() {
<span class="hljs-addition">+    yield takeEvery(types.INCREMENT_ASYNC,increment);</span>
}
</code></pre>
<h3 id="t209.2 redux-saga/index.js">9.2 redux-saga/index.js <a href="#t209.2 redux-saga/index.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fork</span>(<span class="hljs-params">task</span>) </span>{
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">type</span>: <span class="hljs-string">&apos;fork&apos;</span>,
        task
    }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">takeEvery</span>(<span class="hljs-params">actionType,task</span>) </span>{
    <span class="hljs-keyword">yield</span> fork(<span class="hljs-function"><span class="hljs-keyword">function</span>* (<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
            <span class="hljs-keyword">yield</span> take(actionType);
            <span class="hljs-keyword">yield</span> task();
        }
    });
}
</code></pre>
<h3 id="t219.3 redux-saga/index.js">9.3 redux-saga/index.js <a href="#t219.3 redux-saga/index.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">switch</span> (effect.type) {
            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;take&apos;</span>:
                channel.subscribe(effect.actionType,next);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;put&apos;</span>:
                dispatch(effect.action);
                next();
                <span class="hljs-keyword">break</span>;
+            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;fork&apos;</span>:
+                run(effect.task);
+                next();
        <span class="hljs-keyword">default</span>:
}
</code></pre>
<h2 id="t2210 &#x652F;&#x6301;promise">10 &#x652F;&#x6301;promise <a href="#t2210 &#x652F;&#x6301;promise"> # </a></h2>
<h3 id="t2310.1 saga.js">10.1 saga.js <a href="#t2310.1 saga.js"> # </a></h3>
<pre><code class="lang-diff">import {put,take,takeEvery} from &apos;./redux-saga/effects&apos;;
import * as types from &apos;./store/action-types&apos;;
const delay=ms =&gt; new Promise((resolve,reject) =&gt; {
    setTimeout(() =&gt; {
        resolve();
    },ms);
});
export function* increment() {
<span class="hljs-addition">+    yield delay(1000);</span>
    yield put({type:types.INCREMENT});
}

export function* rootSaga() {
    yield takeEvery(types.INCREMENT_ASYNC,increment);
}
</code></pre>
<h3 id="t2410.2 redux-saga/index.js">10.2 redux-saga/index.js <a href="#t2410.2 redux-saga/index.js"> # </a></h3>
<pre><code class="lang-diff">if (typeof effect[Symbol.iterator]==&apos;function&apos;) {
                        run(effect);
                        next();
<span class="hljs-addition">+} else if (effect.then) {</span>
<span class="hljs-addition">+    effect.then(next);</span>
}
</code></pre>
<h2 id="t2511 &#x652F;&#x6301; call">11 &#x652F;&#x6301; call <a href="#t2511 &#x652F;&#x6301; call"> # </a></h2>
<h3 id="t2611.1 sagas.js">11.1 sagas.js <a href="#t2611.1 sagas.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">//yield delay(1000);</span>
    <span class="hljs-keyword">yield</span> call(delay,<span class="hljs-number">1000</span>);
    <span class="hljs-keyword">yield</span> put({<span class="hljs-attr">type</span>:types.INCREMENT});
}
</code></pre>
<h3 id="t2711.2 effects.js">11.2 effects.js <a href="#t2711.2 effects.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">call</span>(<span class="hljs-params">fn,...args</span>) </span>{
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">type</span>: <span class="hljs-string">&apos;call&apos;</span>,
        fn,
        args
    }
}
</code></pre>
<h3 id="t2811.3 saga.js">11.3 saga.js <a href="#t2811.3 saga.js"> # </a></h3>
<pre><code class="lang-js">    <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;call&apos;</span>:
        effect.fn(...effect.args).then(next);
    <span class="hljs-keyword">break</span>;
</code></pre>
<h2 id="t2912. &#x652F;&#x6301;all">12. &#x652F;&#x6301;all <a href="#t2912. &#x652F;&#x6301;all"> # </a></h2>
<h3 id="t3012.1 &#x4F7F;&#x7528;">12.1 &#x4F7F;&#x7528; <a href="#t3012.1 &#x4F7F;&#x7528;"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {put,take,takeEvery,call,all} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./redux-saga/effects&apos;</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> types <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./store/action-types&apos;</span>;

<span class="hljs-keyword">const</span> delay=<span class="hljs-function"><span class="hljs-params">ms</span> =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve,reject</span>) =&gt;</span> {
    setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        resolve();
    },ms);
});
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">increment</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> call(delay,<span class="hljs-number">1000</span>);
    <span class="hljs-keyword">yield</span> put({<span class="hljs-attr">type</span>:types.INCREMENT});
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">incrementWatcher</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> takeEvery(types.INCREMENT_ASYNC,increment);
}
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">logger</span>(<span class="hljs-params">action</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;action&apos;</span>,action);
}
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">loggerWatcher</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> takeEvery(types.INCREMENT_ASYNC,logger);
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">rootSaga</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> all([loggerWatcher(),incrementWatcher()]);
}
</code></pre>
<h3 id="t3112.2 effects">12.2 effects <a href="#t3112.2 effects"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">all</span>(<span class="hljs-params">fns</span>) </span>{
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">type</span>: <span class="hljs-string">&apos;all&apos;</span>,
        fns
    }
}
</code></pre>
<h3 id="t3212.3 redux-saga/index.js">12.3 redux-saga/index.js <a href="#t3212.3 redux-saga/index.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createSagaMiddleware</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createChannel</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">let</span> listener={};
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subscribe</span>(<span class="hljs-params">actionType,cb</span>) </span>{
            listener[actionType]=listener[actionType]? [...listener[actionType],cb]:[cb];
        }
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">publish</span>(<span class="hljs-params">action</span>) </span>{
            <span class="hljs-keyword">if</span> (listener[action.type]) {
                <span class="hljs-keyword">let</span> temp=listener[action.type];
                <span class="hljs-keyword">delete</span> listener[action.type];
                temp.forEach(<span class="hljs-function"><span class="hljs-params">cb</span>=&gt;</span>cb(action));
            }
        }
        <span class="hljs-keyword">return</span> {subscribe,publish}
    }
    <span class="hljs-keyword">let</span> channel=createChannel();

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">times</span>(<span class="hljs-params">cb,total</span>) </span>{
        <span class="hljs-keyword">let</span> count=<span class="hljs-number">0</span>;
        <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">if</span> (++count == total) {
                cb();
            }
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sagaMiddleware</span>(<span class="hljs-params">{getState,dispatch}</span>) </span>{
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">run</span>(<span class="hljs-params">generator,callback</span>) </span>{
            <span class="hljs-keyword">let</span> it= <span class="hljs-keyword">typeof</span> generator == <span class="hljs-string">&apos;function&apos;</span>? generator():generator;
            <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">next</span>(<span class="hljs-params">action</span>) </span>{
                <span class="hljs-keyword">let</span> {<span class="hljs-attr">value</span>:effect,done} = it.next(action);
                <span class="hljs-keyword">if</span> (!done) {
                    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> effect[<span class="hljs-built_in">Symbol</span>.iterator]==<span class="hljs-string">&apos;function&apos;</span>) {
                        run(effect);
                        next();
                    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (effect.then) {
                        effect.then(next);
                    }
                    <span class="hljs-keyword">else</span> {
                        <span class="hljs-keyword">switch</span> (effect.type) {
                            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;take&apos;</span>:
                                channel.subscribe(effect.actionType,next);
                                <span class="hljs-keyword">break</span>;
                            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;put&apos;</span>:
                                dispatch(effect.action);
                                next();
                                <span class="hljs-keyword">break</span>;
                            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;call&apos;</span>:
                                effect.fn(...effect.args).then(next);
                                <span class="hljs-keyword">break</span>;
                            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;all&apos;</span>:
                                <span class="hljs-keyword">let</span> fns=effect.fns;
                                <span class="hljs-keyword">let</span> done=times(next,fns.length);
                                <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i=<span class="hljs-number">0</span>;i&lt;fns.length;i++){
                                    <span class="hljs-keyword">let</span> fn=fns[i];
                                    run(fn,done);
                                }
                                <span class="hljs-keyword">break</span>;
                            <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;fork&apos;</span>:
                                run(effect.task);
                                next();
                            <span class="hljs-keyword">default</span>:
                        }
                    }
                } <span class="hljs-keyword">else</span> {
                    callback&amp;&amp;callback();
                }
            }
            next();
        }
        sagaMiddleware.run=run;
        <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">next</span>) </span>{
            <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">action</span>) </span>{
                channel.publish(action);
                next(action);
            }
        }
    }
    <span class="hljs-keyword">return</span> sagaMiddleware;
}
</code></pre>
<h2 id="t3313. &#x8D44;&#x6E90;">13. &#x8D44;&#x6E90; <a href="#t3313. &#x8D44;&#x6E90;"> # </a></h2>
<ul>
<li><a href="https://github.com/zalmoxisus/redux-devtools-extension">redux-devtools-extension</a></li>
<li><a href="https://github.com/reactjs/react-router-redux">react-router-redux</a></li>
<li><a href="https://github.com/redux-saga/redux-saga">redux-saga</a></li>
<li><a href="https://gitee.com/zhufengpeixun/zhufeng-redux-saga2">zhufeng-redux-saga2</a></li>
<li><a href="https://gitee.com/zhufengpeixun/zhufeng-saga2">zhufeng-saga2</a></li>
</ul>
<h3 id="t3413.1 Iterator">13.1 Iterator <a href="#t3413.1 Iterator"> # </a></h3>
<p>&#x904D;&#x5386;&#x5668;&#xFF08;Iterator&#xFF09;&#x5C31;&#x662F;&#x8FD9;&#x6837;&#x4E00;&#x79CD;&#x673A;&#x5236;&#x3002;&#x5B83;&#x662F;&#x4E00;&#x79CD;&#x63A5;&#x53E3;&#xFF0C;&#x4E3A;&#x5404;&#x79CD;&#x4E0D;&#x540C;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x63D0;&#x4F9B;&#x7EDF;&#x4E00;&#x7684;&#x8BBF;&#x95EE;&#x673A;&#x5236;&#x3002;&#x4EFB;&#x4F55;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x53EA;&#x8981;&#x90E8;&#x7F72; Iterator &#x63A5;&#x53E3;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x5B8C;&#x6210;&#x904D;&#x5386;&#x64CD;&#x4F5C;&#xFF08;&#x5373;&#x4F9D;&#x6B21;&#x5904;&#x7406;&#x8BE5;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x7684;&#x6240;&#x6709;&#x6210;&#x5458;&#xFF09;&#x3002;
Iterator &#x7684;&#x4F5C;&#x7528;&#x6709;&#x4E09;&#x4E2A;&#xFF1A;</p>
<ul>
<li>&#x4E00;&#x662F;&#x4E3A;&#x5404;&#x79CD;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF0C;&#x63D0;&#x4F9B;&#x4E00;&#x4E2A;&#x7EDF;&#x4E00;&#x7684;&#x3001;&#x7B80;&#x4FBF;&#x7684;&#x8BBF;&#x95EE;&#x63A5;&#x53E3;&#xFF1B;</li>
<li>&#x4E8C;&#x662F;&#x4F7F;&#x5F97;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x7684;&#x6210;&#x5458;&#x80FD;&#x591F;&#x6309;&#x67D0;&#x79CD;&#x6B21;&#x5E8F;&#x6392;&#x5217;&#xFF1B;</li>
<li>&#x4E09;&#x662F; ES6 &#x521B;&#x9020;&#x4E86;&#x4E00;&#x79CD;&#x65B0;&#x7684;&#x904D;&#x5386;&#x547D;&#x4EE4;for...of&#x5FAA;&#x73AF;&#xFF0C;Iterator &#x63A5;&#x53E3;&#x4E3B;&#x8981;&#x4F9B;for...of&#x6D88;&#x8D39;&#x3002;</li>
</ul>
<p>&#x539F;&#x751F;&#x5177;&#x5907; Iterator &#x63A5;&#x53E3;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#x3002;</p>
<ul>
<li>Array</li>
<li>Map</li>
<li>Set</li>
<li>String</li>
<li>TypedArray</li>
<li>&#x51FD;&#x6570;&#x7684; arguments &#x5BF9;&#x8C61;</li>
<li>NodeList &#x5BF9;&#x8C61;</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {
  [<span class="hljs-built_in">Symbol</span>.iterator] : <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">next</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">return</span> {
          <span class="hljs-attr">value</span>: <span class="hljs-number">1</span>,
          <span class="hljs-attr">done</span>: <span class="hljs-literal">true</span>
        };
      }
    };
  }
};
</code></pre>

        <div class="copyright">Powered by <a href="https://github.com/jaywcjlove/idoc" target="_blank">idoc</a>. Dependence <a href="https://nodejs.org">Node.js</a> run.</div>
    </div>
    
</div>

<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.js"></script>
<script>
$('.warpper .page-toc ul ul li a').on('click',function(){
  $('.warpper .page-toc ul ul li a').removeClass('my-active')
  $(this).addClass('my-active')
})
  // if (!$('.understand-me').length) {
  //   var bar = $(window).height() - $('.navbar ').height() - $('.page-toc').position().top;
  //   var count = bar / 26 / 2;
  //   var barHeight = $('.page-toc').outerHeight();
  //   $('.page-toc li').eq(0).children('a').addClass('red');
  //   var arr = [];
  //   $("h1,h2,h3,h4,h5,h6").each(function () {
  //     arr.push($(this).position().top);
  //   });
  //   var timer
  //   function dark() {
  //     clearTimeout(timer)
  //      timer = setTimeout(function () {
  //      var top = Math.abs($('.page-toc > ul').position().top);
  //      var cur = $('.content').scrollTop();
  //      for (var i = arr.length; i >= 0; i--) {
  //        if (arr[i] <= cur) {
  //          break;
  //        }
  //      }
  //      if (i === -1) {
  //        i = 0;
  //      }
  //      $('.page-toc li a').removeClass('red');
  //      $('.page-toc li').eq(i).children('a').addClass('red');
  //      let height = $('.page-toc li').eq(i).position().top-$('.page-toc').height(); // 如果当前的offset出去了 回到中间可好？
  //      $('.page-toc').scrollTop(height+$('.page-toc').height()/2);
  //    },200)
  //   }

  //   $('.content').on('scroll', dark);
  // }
</script>
<style>

    /* ::-webkit-scrollbar{width:14px;}
    ::-webkit-scrollbar-track{background-color:transparent;}
    ::-webkit-scrollbar-thumb{background-color:transparent;}
    ::-webkit-scrollbar-thumb:hover {background-color:transparent}
    ::-webkit-scrollbar-thumb:active {background-color:transparent} */

    .page-toc > ul .red {
        background: #f3f3f3;
        z-index: 1;
        border-left: 3px solid #009a61;
        -webkit-transition: all .2s ease;
        transition: all .2s ease;
        color: #000
    }





</style>
</body>
</html>
